package me.zhengjie.modules.web.service.pay.gateway;

import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.util.SignUtils;
import me.zhengjie.config.constant.WeChatConstant;
import me.zhengjie.config.exception.WeChatException;
import me.zhengjie.modules.system.domain.UserChatOrder;
import me.zhengjie.modules.system.service.UserChatOrderService;
import me.zhengjie.modules.web.domain.ReturnPayInfoVO;
import me.zhengjie.modules.web.domain.pay.PayGatewayRequest;
import me.zhengjie.modules.web.service.pay.IPayGatewayService;
import me.zhengjie.modules.weixin.utils.OrderUtil;
import me.zhengjie.utils.DateUtil;
import me.zhengjie.utils.StringUtils;
import me.zhengjie.utils.enums.OrderTypeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 王宇
 */
@Service
public class ChatBaiduPayGatewayServiceImpl implements IPayGatewayService {

    private static final Logger log = LoggerFactory.getLogger(ChatBaiduPayGatewayServiceImpl.class);

    @Autowired
    private UserChatOrderService chatOrderService;

    @Autowired
    private WxPayService wxPayService;

    @Override
    public int orderType() {
        return OrderTypeEnum.Chat.getOrderType();
    }

    @Override
    public ReturnPayInfoVO execute(PayGatewayRequest request) {
        UserChatOrder one = chatOrderService.findOne(request.getOrderSn());
        if (null == one){
            throw new WeChatException("非法请求");
        }
        if (one.getChatAmount().compareTo(BigDecimal.ZERO) <= 0){
            throw new WeChatException("该订单不需要支付");
        }
        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
        wxPayUnifiedOrderRequest.setOpenid(request.getOpenId());
        wxPayUnifiedOrderRequest.setNotifyUrl(WeChatConstant.notifyUrl);
        wxPayUnifiedOrderRequest.setSpbillCreateIp(InetAddress.getLoopbackAddress().getHostAddress());
        wxPayUnifiedOrderRequest.setBody("慧识人AI助手");
        wxPayUnifiedOrderRequest.setTotalFee(one.getChatAmount().multiply(new BigDecimal(100)).intValue());
        wxPayUnifiedOrderRequest.setOutTradeNo(one.getOrderNo());
        wxPayUnifiedOrderRequest.setTradeType("JSAPI");
        WxPayUnifiedOrderResult wxPayUnifiedOrderResult = null;
        try {
            wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);
        } catch (WxPayException e) {
            log.error("调用微信统一创单接口异常",e);
            throw new WeChatException(e.getErrCode(),e.getErrCodeDes());
        }
        if (null == wxPayUnifiedOrderResult || StringUtils.isBlank(wxPayUnifiedOrderResult.getPrepayId())){
            throw new WeChatException("支付异常");
        }
        one.setPrePayid(wxPayUnifiedOrderResult.getPrepayId());
        one.setUpdateTime(DateUtil.TimestampNow());
        chatOrderService.update(one);
        //组合参数构建支付
        Map<String, String> paySignInfo = new HashMap<>(5);
        String timeStamp = OrderUtil.GetTimestamp();
        String nonceStr = OrderUtil.CreateNoncestr();
        paySignInfo.put("appId", WeChatConstant.appid);
        paySignInfo.put("nonceStr", nonceStr);
        paySignInfo.put("timeStamp", timeStamp);
        paySignInfo.put("signType", "MD5");
        paySignInfo.put("package", "prepay_id=" + wxPayUnifiedOrderResult.getPrepayId());
        String paySign = SignUtils.createSign(paySignInfo, WeChatConstant.partnerKey);
        //组合支付参数
        ReturnPayInfoVO returnPayInfoVO = new ReturnPayInfoVO();
        returnPayInfoVO.setAppId(WeChatConstant.appid);
        returnPayInfoVO.setNonceStr(nonceStr);
        returnPayInfoVO.setPaySign(paySign);
        returnPayInfoVO.setSignType("MD5");
        returnPayInfoVO.setPrepayId(wxPayUnifiedOrderResult.getPrepayId());
        returnPayInfoVO.setTimeStamp(timeStamp);
        return returnPayInfoVO;
    }
}
